import baseConfig from './baseConfig.js'
import { isFunction } from '@/utils/is.js'
import { cloneDeep, setObjToString } from '@/utils/common.js'
import store from '@/store'
const isLoadPage = {
  ISSHIP: true
}

const transform = {
  requestBeforeHook: (config, options) => { // 请求前处理config
    // 将token携带在headers中
    const token = store.state.token || uni.getStorageSync('token')
    if (token) {
      config.header = { ...config.header, Authorization:  'Bearer ' + token }
    }
    config.header = { ...config.header, platform: 'MINI',version: baseConfig.versionNumber }
    const { apiURL, postJoinParamsToUrl } = options
    config.url = apiURL ? apiURL + config.url : config.url
    // 处理method请求大写--uni-app必须要大写
    config.method = config.method.toUpperCase()
    // post请求--参数需要拼接到url后面
    if (config.method === 'POST' && postJoinParamsToUrl) {
      config.url = setObjToString(config.url, config.data)
    }
    return config
  }
}

export class VRequest {
  constructor(options) {
    this.options = options
  }

  /**
  * @description 获取options中的转化对象
  * @returns {Object} transform
  */
  getTransform() {
    const { transform } = this.options
    return transform
  }

  /**
  * @description request请求方法
  */
  request(config, options) {
    let conf = cloneDeep(config)
    const transform = this.getTransform()
    const { requestBeforeHook } = transform || {}
    const { requestOptions } = this.options
    // 合并对象
    const opt = Object.assign({}, requestOptions, options)
    // 处理请求前的config
    if (requestBeforeHook && isFunction(requestBeforeHook)) {
      conf = requestBeforeHook(conf, opt)
    }
    return new Promise(async (resolve, reject) => {
      const [error, res] = await uni.request(conf)
      if(error && error.errMsg){// 失败--系统或者网络方面的原因
        uni.showToast({ // 可以关闭loading
          title: '网络超时，请重试',
          icon: 'none'
        });
        reject(error)
      }else if(res && res.statusCode !== 200){// 请求错误或者参数错误
        uni.showToast({ // 可以关闭loading
          title: '请求错误或者参数错误',
          icon: 'none'
        });
        reject(error)
      }else if((res && res.data && res.data.code === 200) || opt.isTransformResult){ // 成功 或者 页面单独处理
        resolve(res.data)
      }else{ // 业务报错
        let codeArr = [1004,1005,1006,1003] // 登录失效
        let pageUrlArr = ['pages/index/index','pages/my/index']
        if (codeArr.includes(res.data.code)) {
          store.commit('USERINFO', {})
          store.commit('TOKEN', '')
          uni.setStorageSync('token', '')
          const routes = getCurrentPages()
          // TODO:此时代码return之后，调用时捕获不到错误
          // if (pageUrlArr.includes(routes[routes.length - 1].route)) return // 底部菜单路由不自动跳转登录
          if (!pageUrlArr.includes(routes[routes.length - 1].route)) {
            // 底部菜单路由不自动跳转登录
            if(isLoadPage.ISSHIP){
              isLoadPage.ISSHIP = false
              setTimeout(() => {
                isLoadPage.ISSHIP = true
              }, 1000);
              store.commit('IS_REFRESH_TYPE', true) // 跳转登录页面存个状态，用来判断页面是否要刷新数据
              uni.navigateTo({url: '/pagesB/login/index'})
            }
          }
        }else{
          // 上面代码是为了兼容老登陆处理
          res.data.code !== 8001 && uni.showToast({// 可以关闭loading
            title: res?.data?.desc ?? '请求错误',
            icon: 'none'
          });
        }
        reject(res.data)
      }
    })
  }

}

export const requestInstance = new VRequest({
  transform,
  // 配置项--以下配置都能在独立的接口请求中被覆盖
  requestOptions: {
    // 是否需要对返回数据进行处理
    isTransformResult: false,
    // post请求的时候参数拼接在url上
    postJoinParamsToUrl: false,
    // 接口地址
    apiURL: process.env.NODE_ENV === 'production' ? baseConfig.production : baseConfig.development
  }
})

// 将request的this指向VRequest
export default requestInstance.request.bind(requestInstance)